package org.example;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseEventSink;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;


@Path("/event")
public class EventResource {
    @Context
    private Sse sse;
    private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);

    @GET
    @Path("/stream")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void streamEvents(@Context SseEventSink eventSink) {
        ScheduledFuture<?> scheduledFuture = executorService.scheduleAtFixedRate(() -> {
            try {
                eventSink.send(sse.newEvent("message","Message sent at: " + System.currentTimeMillis()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 0, 10000, TimeUnit.MICROSECONDS);

        // 在两分钟后取消定时任务并关闭SseEventSink
        executorService.schedule(() -> {
            eventSink.send(sse.newEvent("message sent End at: " + System.currentTimeMillis()));
            scheduledFuture.cancel(false);
            eventSink.close();
        }, 2, TimeUnit.MINUTES);
    }


    ExecutorService executor = Executors.newFixedThreadPool(30);

    @GET
    @Path("/stream2")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void getCheckpointDetailUsedByCucumber(@Context HttpServletResponse response) throws IOException {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");

        try (PrintWriter out = response.getWriter()) {
            out.write("event: message\n");
            out.write("data: Start \n\n");
            out.flush();
            executor.execute(() -> {
                try {
                    Thread.sleep(35000); // 子线程执行120秒
                    out.write("event: message\n");
                    out.write("data:哈哈哈\n\n");
                    out.flush();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            try {
                // awaitTermination返回false即超时会继续循环，返回true即线程池中的线程执行完成主线程跳出循环往下执行，每隔10秒循环一次
                while (!executor.awaitTermination(5000, TimeUnit.MILLISECONDS)){
                    out.write("event: message\n");
                    out.write("data: Hello!!!! " + System.currentTimeMillis() + "\n\n");
                    out.flush();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.write("event: message\n");
            out.write("data: Hello End\n\n");
            out.flush();
        }
        System.out.println("子线程执行完毕，主线程结束");
    }
}


